/*
 * Copyright (c) 2002-2007 by OpenSymphony
 * All rights reserved.
 */
package com.googlecode.s2ss.plugin.groovy;

import groovy.util.GroovyScriptEngine;
import groovy.util.ResourceException;
import groovy.util.ScriptException;

import java.net.URL;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.impl.StrutsObjectFactory;

import com.opensymphony.xwork2.config.entities.ActionConfig;

/**
 * A very first test for a standalone Groovy ObjectFactory to use as a Struts 2
 * plugin. Hardly production ready (well, not really tested at least), but
 * should be fun to play with.
 * 
 * As always, use at your own risk, etc ..
 * 
 * Date: March 9, 2007
 * 
 * @author Philip Luppens
 * @version 0.2
 * 
 */
public class GroovyObjectFactory extends StrutsObjectFactory {

	private final static Log logger = LogFactory.getLog(GroovyObjectFactory.class);

	private final static String GROOVY_EXTENSION = ".groovy";

	private GroovyScriptEngine gse;


	/**
	 * Default constructor.
	 */
	public GroovyObjectFactory() {
		super();
		init();
	}

	private void init() {
		gse = new GroovyScriptEngine(new URL[] { getClass().getResource("/") });
		logger.info("Groovy Objectfactory initialized");
	}

	@Override
	public Class getClassInstance(String className) throws ClassNotFoundException {
		if (!className.endsWith(GROOVY_EXTENSION)) {
			return super.getClassInstance(className);
		} else {
			Class clz = null;
			try {
				className = className.substring(0, className.length() - GROOVY_EXTENSION.length());
				clz = getScript(className);
			} catch (Exception e) {
				logger.error(e);
			}
			return clz;
		}
	}

	@Override
	public Object buildAction(String actionName, String namespace, ActionConfig config, Map extraContext)
			throws Exception {
		return buildBean(config.getClassName(), extraContext);
	}

	private Class getScript(String className) throws ResourceException, ScriptException {
		Class groovyClass = gse.loadScriptByName(className);
		return groovyClass;
	}
}
